#include "filesonic.h"
#include <QRegExp>
#include <QDebug>
#include <commonutils.h>
#include <QStringList>
#include "captchasolver.h"
#include <QTimer>
#include "links/link.h"


#define formName    "<div id=\"intro\">"
#define recaptcha   "captchaVerification"
#define pobierz     "Start download"
#define usuniety    "This file was deleted"
#define delay       "freeUserDelay"
#define in_use      "download 1 file at a time"

const QString FileSonic::site="www.filesonic.com www.filesonic.pl";

FileSonic::FileSonic()
{

    //qDebug()<<"1";
    pendingHash=-1;
    connect(&imgLocator, SIGNAL(imageLocated(QString, QString)), this, SLOT(imgLocated(QString, QString)));
    connect(CaptchaSolver::getInstance(), SIGNAL(solved(int,QString)), this, SLOT(captchaCompetition(int, QString)));
}

QString FileSonic::type(){
    //qDebug()<<"2";
    return site;
}

int FileSonic::checkPhase(QString page){
    //qDebug()<<"3";
    //qDebug()<<page;
    if(page.contains(pobierz)){
       // qDebug()<<"file";
        return SiteParser::GET_FILE;
    }else if(page.contains(recaptcha)){
        //qDebug()<<"captcha";
        return SiteParser::GET_CAPTCHA;
    }else if(page.contains(delay)){
        //qDebug()<<"delay";
        return checkLongDelay(page);
    }else if(page.contains(usuniety)){
        //qDebug()<<"usuniety";
        return SiteParser::FILE_DELETED;
    }else if(page.contains(in_use)){
        //qDebug()<<"usuniety";
        return SiteParser::IN_USE;
    }else if(page.contains(formName)){
        //qDebug()<<"form";
        return SiteParser::GET_FORM;
    }
    qDebug()<<"=============nic===============";
    return -1;
};

void FileSonic::parsePage(QString page){
    //qDebug()<<"10";
    //qDebug()<<checkPhase(page);
    switch(checkPhase(page)){
    case SiteParser::GET_FORM:
       getForm(page);
        break;
    case SiteParser::GET_CAPTCHA:
        emit info(Link::INFO_CAPTCHA);
       solveCaptcha(page);
        break;
    case SiteParser::SHORT_DELAY:
        emit info(Link::INFO_SHORT_DELAY);
       shortDelay(page);
        break;
    case SiteParser::LONG_DELAY:
        emit wait(getDelay());
        break;
    case SiteParser::GET_FILE:
       getFile(page);
        break;
    case SiteParser::FILE_DELETED:
       emit error(Link::ERR_DELETED);
        break;
    case SiteParser::IN_USE:
       emit wait(180);//lest try to wait 3 minutes
        break;
    default:
        qDebug()<<"Nierozpoznana strona:";
        qDebug()<<page;
    };
}


void FileSonic::solveCaptcha(QString page){
    //qDebug()<<"4";
    int last = page.lastIndexOf("\"capt");
    page = page.left(last-3);
    int ktore = page.indexOf("Recaptcha.create");
    ktore = page.length()-ktore-18;
    page = page.right(ktore);
    QString form;
    form = "http://api.recaptcha.net/noscript?k=";
    form.append(page);
    path=*(CommonUtils::getFormPath(form));
    post=*(CommonUtils::getFormPost(form));
    imgLocator.getImgAddress(form);
}

void FileSonic::imgLocated(QString address, QString challange){
    //qDebug()<<"5";
   // qDebug()<< __FILE__<<":"<<__LINE__<<"\t"<< path;
   // qDebug()<<"adres: " <<address;
    pendingHash=CaptchaSolver::getInstance()->solve(address);
        CaptchaSolver::getInstance()->getCaptchaDesc(pendingHash)->setChallange(challange);
};

int FileSonic::checkLongDelay(QString page){
    QString delayDiv = CommonUtils::getTagContaining(page,"div","downloadMode");
    QRegExp reg("var countDownDelay = (\\d+);");
    if(reg.indexIn(delayDiv)==-1){
        qDebug()<<"Nierozpoznany delay \n"<<delayDiv;
    };
    delayTime=reg.cap(1).toInt();
    //qDebug()<<"Found delay "<< delayTime;
    if(delayDiv.contains("tm_hash")){
        return SiteParser::SHORT_DELAY;
    }else{
        return SiteParser::LONG_DELAY;
    }

}

void FileSonic::shortDelay(QString page){
    QString form=CommonUtils::getTagContaining(page,"div", "downloadMode"); //wyszukiwanie hrefow
    if(!form.isEmpty()){
        QString inpTxt=CommonUtils::getTagContaining(form,"input", "tm");
        QUrl url;
        QRegExp nazwa("name=\\'([^\'']*)");
        QRegExp wartosc("value=\\'([^\'']*)");
        if((nazwa.indexIn(inpTxt, 0)!=-1)&&(wartosc.indexIn(inpTxt, 0)!=-1)){
            url.addQueryItem(nazwa.cap(1),wartosc.cap(1));
        }

        inpTxt=CommonUtils::getTagContaining(form,"input", "tm_hash");
        if((nazwa.indexIn(inpTxt, 0)!=-1)&&(wartosc.indexIn(inpTxt, 0)!=-1)){
            url.addQueryItem(nazwa.cap(1),wartosc.cap(1));
        }
        QString tmp=url.toString();

        //qDebug()<<"Waiting about 1 minute";
        startTm=QTime::currentTime();
        tm=new QTimer;
        connect(tm, SIGNAL(timeout()), this, SLOT(timeout()));
        tm->start(4000);

        path="";
        post= tmp.right(tmp.length()-1);
        return;
    }

    qDebug()<< __FILE__<<":"<<__LINE__<<"\t"<< "didnt found form";
}

void FileSonic::getForm(QString page){
    QString form =CommonUtils::getTagContaining(page,"a", "free_download"); //wyszukiwanie hrefow
    if(!form.isEmpty()){
        int x = form.lastIndexOf("href");
        QString form2 = form;
        form2.remove(0,x+6);
        x = form2.indexOf("\"");
        form2 = form2.left(x);
        //form2 = form2.append("?start=1");
        path=form2;
        post=" ";
       // qDebug()<<post;

        /*qDebug()<<"Waiting about 1 minute";
            startTm=QTime::currentTime();
            tm=new QTimer;
            connect(tm, SIGNAL(timeout()), this, SLOT(timeout()));
            tm->start(4000);
            */
        emit goForm(QUrl(path), post);
        return;
    }

    qDebug()<< __FILE__<<":"<<__LINE__<<"\t"<< "didnt found form";

}

int FileSonic::getDelay(){
    return delayTime;
}

void FileSonic::timeout(){
    //qDebug()<<"8";
    if(startTm.secsTo( QTime::currentTime())>getDelay()){
        //qDebug()<< __FILE__<<":"<<__LINE__<<"\t"<< getDelay() <<" sec timeout";
        emit goForm(QUrl(path), post);
        delete tm;
    }else{
        //qDebug()<<"delayed: "<<startTm.secsTo( QTime::currentTime());
    }
}


void FileSonic::getFile(QString page){
    //get form part of page
    QString form=CommonUtils::getTagContaining(page,"div", pobierz);
    if(!form.isEmpty()){
        QRegExp reg("href=\"([^\"]*)");
        reg.indexIn(form);
        //qDebug()<<"Found file path: "<<reg.cap(1);
        emit goForm(QUrl(reg.cap(1)),"");

    }
}


void FileSonic::captchaCompetition(int hash, QString caption){
    //qDebug()<<"11";
    qDebug()<< __FILE__<<":"<<__LINE__<<"Looking for captcha"<<QString().number(pendingHash)<<"on"<<lPath<<"hash"<<QString().number(hash);
    if(pendingHash==hash){                                                                                                              
        //qDebug()<< __FILE__<<":"<<__LINE__;
        CaptchaDesc* desc=CaptchaSolver::getInstance()->getCaptchaDesc(hash);
        if(desc==NULL){
            qDebug()<< __FILE__<<":"<<__LINE__<<"some strange captcha problem";
            return;
        }
        desc->setCaption(caption);
        //qDebug()<<__FILE__<<__LINE__<<"Testing captioon"<<path;
        //qDebug()<<imgLocator.createPost(desc);

        emit goForm(QUrl(path), imgLocator.createPost(desc));
        CaptchaSolver::getInstance()->rmCaptchaDesc(hash);

        pendingHash=-1;
        disconnect(CaptchaSolver::getInstance(), SIGNAL(solved(int,QString)));
    }
}
